﻿package org.rkuk.kasutil.timeline 
{
	import flash.display.Shape;
	import flash.events.Event;
	/**
	 * 按照帧发出ClockEvent.TICK事件，发出的频率是stage.frameRate，每次发出事件都广播当前的帧数
	 * @author rkuk
	 */
	public class FrameClock extends Clock
	{
		private var _clock:Shape;
		private var _isStarted:Boolean
		
		/**
		 * @private
		 * 已经发出ClockEvent.TICK事件帧数
		 */
		protected var _timePast:int;
		
		/**
		 * @private
		 * 两次ClockEvent.TICK事件之间的间隔，对于FrameClock来说，此值恒定为1
		 */
		protected var _currentTimeStep:int;
		
		/**
		 * 构造函数
		 */
		public function FrameClock() 
		{
			super();
			init();
		}
		
		private function init():void
		{
			_clock = new Shape();
			_timePast = 1;//以Frame计数时，开始是第1帧
			_isStarted = false;
			_currentTimeStep = -1;//-1表示没有开始启动
		}
		
		/**
		 * @inheritDoc
		 */
		override public function start(immediately:Boolean=false):void 
		{
			if (!_isStarted)
			{
				_clock.addEventListener(Event.ENTER_FRAME, clockTick);
				_isStarted = true;
				
				if (immediately)
				{
					_currentTimeStep = 0;
					dispatchClockEvent();
				}
				//在非immediately刷新时，启动之后不是立即刷新
				//因此此时虽然启动了，但是在稍后的刷新之前，_currentTimeStep还是为-1
			}
		}
		
		/**
		 * @inheritDoc
		 */
		override public function stop():void 
		{
			if (_isStarted)
			{
				_clock.removeEventListener(Event.ENTER_FRAME, clockTick);
				_isStarted = false;
				_currentTimeStep = -1;
			}
		}
		
		/**
		 * @inheritDoc
		 */
		override public function get currentTime():int
		{
			return _timePast;
		}
		
		/**
		 * @inheritDoc
		 */
		override public function get currentTimeStep():int
		{
			return _currentTimeStep;
		}
		
		/**
		 * @inheritDoc
		 */
		override public function get isStarted():Boolean
		{
			return _isStarted;
		}
		
		/**
		 * @private
		 * 响应EnterFrame事件的函数，实现更新当前时间和刷新时间间隔，并发出ClockEvent.TICK事件
		 */
		protected function clockTick(e:Event):void
		{
			_timePast++;
			_currentTimeStep = 1;
			dispatchClockEvent();
		}
		
		/**
		 * @private
		 */
		protected function dispatchClockEvent():void
		{
			var e:ClockEvent = new ClockEvent(_timePast,_currentTimeStep,ClockEvent.TICK);
			dispatchEvent(e);
		}
	}

}